#pragma once

#include <Ogre.h>
#include "Constants.h"
typedef std::map<Ogre::String, Ogre::Bone*> spiderBoneList;

//STRUCT SPIDER BONES
struct SpiderBones{
	SpiderBones(const Ogre::String b1, const Ogre::String b2, const Ogre::String b3)
		: BONE1(b1), BONE2(b2), BONE3(b3)
	{}
	const Ogre::String BONE1, BONE2, BONE3;
};

class BoneSet;
class SpiderManager
{
	private:
		SpiderManager(void);
		~SpiderManager(void){}
		
	public:

		Ogre::Vector3 wp(Ogre::SceneNode* _node, Ogre::Bone* _bone);// returns given bone's world position
		
		static SpiderManager*		getSingletonPtr();
		void						initialize(Ogre::SceneManager* sceneManager, Ogre::Root* root); //initialize singleton... can only be called once
		Ogre::Entity*				getSpiderEntity();
		Ogre::SceneNode*			getSpiderSceneNode();
		Ogre::Skeleton*				getSpiderSkeleton();
		Ogre::SceneManager*			getSMngr();
		Ogre::Root*					getRoot();
		spiderBoneList&				getSpiderBonesList();

	
		void						setSpiderEntity(Ogre::Entity* entity);
		void						setSpiderNode(Ogre::SceneNode* node);
		void						setSpiderSkeleton(Ogre::Skeleton* skeleton);
		
		void						updateBones(float deltaTime);

		std::vector<BoneSet*>		boneSets;
		void						createBoneSets();				//Creates the bone, do this after initializing _boneList
	private:
		static SpiderManager*		_instance;
		Ogre::SceneManager*			_sceneManager;
		Ogre::Root*					_root;
		Ogre::Entity*				_spiderEntity;
		Ogre::SceneNode*			_spiderNode;
		Ogre::Skeleton*				_spiderSkeleton;

		
		bool solveIK(Ogre::Vector3 goal,Ogre::Bone* b1,Ogre::Bone* b2,Ogre::Bone* b3);

		spiderBoneList				_boneList;
			



	//root
	static const Ogre::String B_ROOT;
	
	//left bones
	static const SpiderBones B_LEFT_1;
	static const SpiderBones B_LEFT_2;
	static const SpiderBones B_LEFT_3;
	static const SpiderBones B_LEFT_4;
	
	//right bones
	static const SpiderBones B_RIGHT_1;
	static const SpiderBones B_RIGHT_2;
	static const SpiderBones B_RIGHT_3;
	static const SpiderBones B_RIGHT_4;

	//others
	static const SpiderBones B_HEAD;
	static const SpiderBones B_TAIL;
		
	
	/*
		//implicit defined guardclass; calls destructor of SpiderManager @ global elementdestruction
		class ReleaseGuard{ 
			public:
				~ReleaseGuard(void){
					if(SpiderManager::_instance != NULL){
						delete SpiderManager::_instance;
						SpiderManager::_instance = NULL;
					}
				}
		};
		friend class ReleaseGuard; //access to private member*/
};
